from flask import request, jsonify, g
from flask_jwt_extended import jwt_required, get_jwt_identity
import datetime
from bson import ObjectId

from app.api.v1 import api_bp
from app import mongo
from app.utils.auth import permission_required
from app.schemas.drug import DrugInventorySchema, DrugInventoryUpdateSchema
from app.utils.common import normalize_data, paginate

@api_bp.route('/drug-inventory', methods=['GET'])
@jwt_required()
@permission_required('drug_inventory:read')
def get_drug_inventory():
    """获取药品库存列表"""
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    sort_by = request.args.get('sortBy', 'expirationDate')
    order = request.args.get('order', 'asc')
    
    # 构建查询条件
    query = {}
    
    # 按药品ID筛选
    drug_id = request.args.get('drugId')
    if drug_id:
        query['drugId'] = drug_id
    
    # 按状态筛选
    status = request.args.get('status')
    if status:
        query['status'] = status
    
    # 按批号搜索
    batch_number = request.args.get('batchNumber')
    if batch_number:
        query['batchNumber'] = {'$regex': batch_number, '$options': 'i'}
    
    # 按库存筛选
    min_quantity = request.args.get('minQuantity')
    if min_quantity:
        try:
            min_quantity = int(min_quantity)
            query['quantity'] = {'$gte': min_quantity}
        except ValueError:
            pass
    
    max_quantity = request.args.get('maxQuantity')
    if max_quantity:
        try:
            max_quantity = int(max_quantity)
            if 'quantity' not in query:
                query['quantity'] = {}
            query['quantity']['$lte'] = max_quantity
        except ValueError:
            pass
    
    # 按有效期筛选
    expiration_before = request.args.get('expirationBefore')
    if expiration_before:
        try:
            expiration_before = datetime.datetime.strptime(expiration_before, '%Y-%m-%d')
            query['expirationDate'] = {'$lte': expiration_before}
        except ValueError:
            pass
    
    expiration_after = request.args.get('expirationAfter')
    if expiration_after:
        try:
            expiration_after = datetime.datetime.strptime(expiration_after, '%Y-%m-%d')
            if 'expirationDate' not in query:
                query['expirationDate'] = {}
            query['expirationDate']['$gte'] = expiration_after
        except ValueError:
            pass
    
    # 确定排序
    sort_direction = 1 if order.lower() == 'asc' else -1
    
    # 获取数据
    inventory_cursor = mongo.db.drug_inventory.find(query).sort(sort_by, sort_direction)
    
    # 分页
    paginated_data = paginate(inventory_cursor, page, limit)
    
    # 标准化数据并添加药品信息
    inventory_items = []
    for item in paginated_data['items']:
        normalized_item = normalize_data(item)
        
        # 获取药品信息
        drug_info = None
        if 'drugId' in item:
            drug_id = item['drugId']
            if ObjectId.is_valid(drug_id):
                drug = mongo.db.drugs.find_one({'_id': ObjectId(drug_id)})
            else:
                drug = mongo.db.drugs.find_one({'_id': drug_id})
            
            if drug:
                drug_info = {
                    'id': str(drug['_id']),
                    'drugCode': drug.get('drugCode', ''),
                    'name': drug.get('name', ''),
                    'specification': drug.get('specification', ''),
                    'manufacturer': drug.get('manufacturer', '')
                }
        
        normalized_item['drugInfo'] = drug_info
        inventory_items.append(normalized_item)
    
    return jsonify({
        'success': True,
        'data': {
            'total': paginated_data['total'],
            'page': paginated_data['page'],
            'limit': paginated_data['per_page'],
            'inventory': inventory_items
        }
    }), 200

@api_bp.route('/drug-inventory', methods=['POST'])
@jwt_required()
@permission_required('drug_inventory:create')
def create_drug_inventory():
    """添加药品库存记录"""
    # 验证请求数据
    schema = DrugInventorySchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 验证药品是否存在
    drug_id = data['drugId']
    drug = None
    if ObjectId.is_valid(drug_id):
        drug = mongo.db.drugs.find_one({'_id': ObjectId(drug_id)})
    
    if not drug:
        drug = mongo.db.drugs.find_one({'_id': drug_id})
    
    if not drug:
        return jsonify({
            'success': False,
            'message': '药品不存在'
        }), 400
    
    # 检查批号是否已存在于该药品
    existing = mongo.db.drug_inventory.find_one({
        'drugId': drug_id,
        'batchNumber': data['batchNumber']
    })
    
    if existing:
        return jsonify({
            'success': False,
            'message': '该批号的库存记录已存在'
        }), 400
    
    # 设置接收人信息
    current_user_id = get_jwt_identity()
    user = mongo.db.users.find_one({'_id': ObjectId(current_user_id)})
    if user:
        data['receiveBy'] = str(user['_id'])
    
    # 设置创建时间和更新时间
    now = datetime.datetime.utcnow()
    data['createdAt'] = now
    data['updatedAt'] = now
    
    # 如果没有设置接收日期，默认为当前时间
    if 'receiveDate' not in data:
        data['receiveDate'] = now
    
    # 检查有效期是否已过期
    if 'expirationDate' in data and isinstance(data['expirationDate'], datetime.datetime):
        if data['expirationDate'] < now:
            data['status'] = '过期'
        elif (data['expirationDate'] - now).days < 90:  # 小于90天视为即将过期
            data['status'] = '即将过期'
    
    # 保存到数据库
    result = mongo.db.drug_inventory.insert_one(data)
    
    return jsonify({
        'success': True,
        'message': '药品库存记录创建成功',
        'data': {
            'id': str(result.inserted_id),
            'drugId': data['drugId'],
            'batchNumber': data['batchNumber'],
            'quantity': data['quantity'],
            'createdAt': now.isoformat()
        }
    }), 201

@api_bp.route('/drug-inventory/<id>', methods=['GET'])
@jwt_required()
@permission_required('drug_inventory:read')
def get_drug_inventory_item(id):
    """获取单个库存记录详情"""
    # 查找库存记录
    if not ObjectId.is_valid(id):
        return jsonify({
            'success': False,
            'message': '无效的库存ID'
        }), 400
    
    inventory = mongo.db.drug_inventory.find_one({'_id': ObjectId(id)})
    if not inventory:
        return jsonify({
            'success': False,
            'message': '库存记录不存在'
        }), 404
    
    # 标准化数据
    normalized_inventory = normalize_data(inventory)
    
    # 获取药品信息
    drug_info = None
    if 'drugId' in inventory:
        drug_id = inventory['drugId']
        if ObjectId.is_valid(drug_id):
            drug = mongo.db.drugs.find_one({'_id': ObjectId(drug_id)})
        else:
            drug = mongo.db.drugs.find_one({'_id': drug_id})
        
        if drug:
            drug_info = normalize_data(drug)
    
    normalized_inventory['drugInfo'] = drug_info
    
    # 获取接收人信息
    receiver_info = None
    if 'receiveBy' in inventory:
        receiver_id = inventory['receiveBy']
        if ObjectId.is_valid(receiver_id):
            user = mongo.db.users.find_one({'_id': ObjectId(receiver_id)})
            if user:
                receiver_info = {
                    'id': str(user['_id']),
                    'name': user.get('name', ''),
                    'username': user.get('username', '')
                }
    
    normalized_inventory['receiverInfo'] = receiver_info
    
    return jsonify({
        'success': True,
        'data': normalized_inventory
    }), 200

@api_bp.route('/drug-inventory/<id>', methods=['PUT'])
@jwt_required()
@permission_required('drug_inventory:update')
def update_drug_inventory(id):
    """更新库存记录"""
    # 验证请求数据
    schema = DrugInventoryUpdateSchema()
    errors = schema.validate(request.json)
    if errors:
        return jsonify({
            'success': False,
            'message': '请求数据验证失败',
            'errors': errors
        }), 400
    
    data = request.json
    
    # 查找库存记录
    if not ObjectId.is_valid(id):
        return jsonify({
            'success': False,
            'message': '无效的库存ID'
        }), 400
    
    inventory = mongo.db.drug_inventory.find_one({'_id': ObjectId(id)})
    if not inventory:
        return jsonify({
            'success': False,
            'message': '库存记录不存在'
        }), 404
    
    # 准备更新数据
    update_data = data.copy()
    update_data['updatedAt'] = datetime.datetime.utcnow()
    
    # 更新数据库
    result = mongo.db.drug_inventory.update_one(
        {'_id': ObjectId(id)},
        {'$set': update_data}
    )
    
    if result.modified_count == 0:
        return jsonify({
            'success': False,
            'message': '库存记录更新失败'
        }), 500
    
    return jsonify({
        'success': True,
        'message': '库存记录更新成功',
        'data': {
            'id': id,
            'quantity': data.get('quantity', inventory.get('quantity')),
            'updatedAt': update_data['updatedAt'].isoformat()
        }
    }), 200

@api_bp.route('/drug-inventory/expiring', methods=['GET'])
@jwt_required()
@permission_required('drug_inventory:read')
def get_expiring_inventory():
    """获取即将过期的库存"""
    # 获取查询参数
    days = request.args.get('days', 90, type=int)
    page = request.args.get('page', 1, type=int)
    limit = request.args.get('limit', 20, type=int)
    expiry_status = request.args.get('expiryStatus', 'all')
    
    # 计算日期范围
    now = datetime.datetime.utcnow()
    expiry_date = now + datetime.timedelta(days=days)
    
    # 打印调试信息
    print(f"查询即将过期药品: days={days}, expiryStatus={expiry_status}, now={now}, expiry_date={expiry_date}")
    
    # 构建查询条件
    query = {'quantity': {'$gt': 0}}
    
    # 根据过期状态筛选 - 注意：由于日期可能是字符串格式，我们需要在后面手动过滤
    # 这里先获取所有有库存的药品，后面再根据日期进行筛选
    
    # 按药品ID筛选
    drug_id = request.args.get('drugId')
    if drug_id:
        query['drugId'] = drug_id
    
    # 按药品名称筛选
    drug_name = request.args.get('drugName')
    if drug_name:
        # 需要先找到匹配名称的药品ID
        drug_ids = []
        drugs = mongo.db.drugs.find({'name': {'$regex': drug_name, '$options': 'i'}})
        for drug in drugs:
            drug_ids.append(str(drug['_id']))
        
        if drug_ids:
            query['drugId'] = {'$in': drug_ids}
        else:
            # 如果没有匹配的药品，返回空结果
            return jsonify({
                'success': True,
                'data': {
                    'total': 0,
                    'page': page,
                    'limit': limit,
                    'inventory': []
                }
            }), 200
    
    # 按药品编码筛选
    drug_code = request.args.get('drugCode')
    if drug_code:
        # 需要先找到匹配编码的药品ID
        drug_ids = []
        drugs = mongo.db.drugs.find({'drugCode': {'$regex': drug_code, '$options': 'i'}})
        for drug in drugs:
            drug_ids.append(str(drug['_id']))
        
        if drug_ids:
            # 如果已经有drugId条件，需要取交集
            if 'drugId' in query:
                if isinstance(query['drugId'], dict) and '$in' in query['drugId']:
                    query['drugId']['$in'] = list(set(query['drugId']['$in']).intersection(set(drug_ids)))
                else:
                    existing_id = query['drugId']
                    if existing_id not in drug_ids:
                        # 没有交集，返回空结果
                        return jsonify({
                            'success': True,
                            'data': {
                                'total': 0,
                                'page': page,
                                'limit': limit,
                                'inventory': []
                            }
                        }), 200
            else:
                query['drugId'] = {'$in': drug_ids}
        else:
            # 如果没有匹配的药品，返回空结果
            return jsonify({
                'success': True,
                'data': {
                    'total': 0,
                    'page': page,
                    'limit': limit,
                    'inventory': []
                }
            }), 200
    
    # 打印最终查询条件
    print(f"查询条件: {query}")
    
    # 获取数据
    inventory_cursor = mongo.db.drug_inventory.find(query).sort('expirationDate', 1)
    
    # 打印查询到的记录数
    count = mongo.db.drug_inventory.count_documents(query)
    print(f"查询到 {count} 条记录")
    
    # 获取所有符合条件的库存记录
    all_inventory = list(inventory_cursor)
    
    # 根据过期状态手动过滤
    filtered_inventory = []
    for item in all_inventory:
        # 处理expirationDate字段
        expiration_date = None
        if 'expirationDate' in item:
            if isinstance(item['expirationDate'], datetime.datetime):
                expiration_date = item['expirationDate']
            elif isinstance(item['expirationDate'], str):
                try:
                    # 尝试解析日期字符串
                    if 'T' in item['expirationDate']:
                        # ISO格式日期
                        expiration_date = datetime.datetime.fromisoformat(item['expirationDate'].replace('Z', '+00:00'))
                    else:
                        # 简单日期格式
                        expiration_date = datetime.datetime.strptime(item['expirationDate'], '%Y-%m-%d')
                except ValueError:
                    print(f"无法解析日期: {item['expirationDate']}")
                    continue
        
        if expiration_date is None:
            continue
        
        # 计算剩余天数
        remaining_days = (expiration_date - now).days
        
        # 根据过期状态筛选
        if expiry_status == 'expired' and remaining_days >= 0:
            continue
        elif expiry_status == 'nearExpiry' and (remaining_days < 0 or remaining_days > days):
            continue
        elif expiry_status == 'all' and remaining_days > days:
            continue
        
        # 添加到过滤后的列表
        filtered_inventory.append(item)
    
    # 手动分页
    total = len(filtered_inventory)
    start_idx = (page - 1) * limit
    end_idx = min(start_idx + limit, total)
    paginated_items = filtered_inventory[start_idx:end_idx]
    
    # 标准化数据并添加药品信息
    inventory_items = []
    for item in paginated_items:
        normalized_item = normalize_data(item)
        
        # 获取药品信息
        drug_info = None
        if 'drugId' in item:
            drug_id = item['drugId']
            if ObjectId.is_valid(drug_id):
                drug = mongo.db.drugs.find_one({'_id': ObjectId(drug_id)})
            else:
                drug = mongo.db.drugs.find_one({'_id': drug_id})
            
            if drug:
                drug_info = {
                    'id': str(drug['_id']),
                    'drugCode': drug.get('drugCode', ''),
                    'name': drug.get('name', ''),
                    'specification': drug.get('specification', ''),
                    'manufacturer': drug.get('manufacturer', '')
                }
        
        normalized_item['drugInfo'] = drug_info
        
        # 计算并添加剩余天数
        if 'expirationDate' in item:
            expiration_date = None
            if isinstance(item['expirationDate'], datetime.datetime):
                expiration_date = item['expirationDate']
            elif isinstance(item['expirationDate'], str):
                try:
                    if 'T' in item['expirationDate']:
                        expiration_date = datetime.datetime.fromisoformat(item['expirationDate'].replace('Z', '+00:00'))
                    else:
                        expiration_date = datetime.datetime.strptime(item['expirationDate'], '%Y-%m-%d')
                except ValueError:
                    pass
            
            if expiration_date:
                remaining_days = (expiration_date - now).days
                normalized_item['remainingDays'] = remaining_days
        
        inventory_items.append(normalized_item)
    
    return jsonify({
        'success': True,
        'data': {
            'total': total,
            'page': page,
            'limit': limit,
            'inventory': inventory_items
        }
    }), 200 